package com.zbs.framework.dao.base;

import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.List;

/**
 * Created by Zbs
 * 2018-11-28 18:12
 */
public class TreeNodeHelper {

    public static String getNewCode(EntityManager em, Class<? extends TreeNode> nodeClass, TreeNode parent) {

        Assert.notNull(em, "em can not be null!");
        Assert.notNull(nodeClass, "nodeClass can not be null!");

        if (parent == null){
            // 查找第一级最大code
            String maxCode = findMaxCodeByLevel(em, nodeClass, 1);
            Integer c = ObjectUtils.isEmpty(maxCode) ? 0 : Integer.valueOf(maxCode);
            // 越界检查
            Assert.isTrue(c < 99, "Tree code out of bound!");
            return String.format("%02d", c + 1);
        }
        // 父级不为空，查找最大code子节点
        String maxCode = findMaxCodeByParentId(em, nodeClass, parent.getId());
        Integer c = ObjectUtils.isEmpty(maxCode) ? 0 : Integer.valueOf(maxCode.substring(maxCode.length() - 2));
        // 越界检查
        Assert.isTrue(c < 99, "Tree code out of bound!");
        return parent.getTreeCode() + String.format("%02d", c + 1);
    }

    private static String findMaxCodeByLevel(EntityManager em, Class<?> nodeClass, int level) {
        Query query = em.createQuery("select max(s.treeCode) from " + nodeClass.getName() + " s where s.level = :level");
        query.setParameter("level", level);
        query.setMaxResults(1);

        List<String> list = query.getResultList();
        return CollectionUtils.isEmpty(list) ? null : list.get(0);
    }

    private static String findMaxCodeByParentId(EntityManager em, Class<?> nodeClass, Long parentId) {
        Query query = em.createQuery("select max(s.treeCode) from " + nodeClass.getName() +" s where s.parentId = :parentId");
        query.setParameter("parentId", parentId);
        query.setMaxResults(1);

        List<String> list = query.getResultList();
        return CollectionUtils.isEmpty(list) ? null : list.get(0);
    }
}
